QT入门(十五) | 您所在的位置:网站首页 › 客户端 服务端 数据库 › QT入门(十五) |
TCP双向通信
效果图一 .pro文件三 .cpp中服务端的内容1.启动服务器2.服务器现有新的连接时关于 **ssocket=sserver.nextPendingConnection();**
3.服务器发现有数据进来时,要去读取数据4.服务端发送数据给客户端
四 .cpp中客户端的内容1.客户端连接服务器2.客户端向服务器发送内容3.客户端接收内容
小结
效果图
一 .pro文件
添加network QT += core gui network二 .h头文件中的定义 private slots: void on_pushButton_clicked(); void on_pushButton_4_clicked(); void on_pushButton_5_clicked(); //客户端读取发送端发来的数据的槽函数 void cread_data(); void on_pushButton_2_clicked(); //客户端点击 连接服务器,连接上会触发服务器发出newConnection的信号,进入receive_clien函数中 void receive_client(); //服务器读取客户端发来的数据的槽函数 void sread_data(); void on_pushButton_3_clicked(); void on_pushButton_6_clicked(); private: Ui::MainWindow *ui; //客户端的套接字 QTcpSocket csocket; //声明一个QTcpserver的对象,用于监听 QTcpServer sserver; //创建服务器的套接字,用于与客户端进行通信 QTcpSocket *ssocket;QTcpSocket *ssocket;服务器的套接字,用于与客户端进行通信。由于这个套接字是在服务器的receive-client这个槽函数中函数中获取的,又要在服务端的发送函数中使用,所以要变成全局变量。 三 .cpp中服务端的内容 1.启动服务器服务端点击启动服务器,服务器就开始监听 //启动服务器 void MainWindow::on_pushButton_2_clicked() { //监听----------启动服务器 //QHostAddress::Any 地址,接纳所有的地址 //端口号 ui->sportEdit->text()获得输入的字符串,转换成无符号短整型 sserver.listen(QHostAddress::Any,ui->sportEdit->text().toUShort()); } 2.服务器现有新的连接时当服务器发现有人要来连接时,就会发出newconnection 的信号,从而触发槽函数receive_client(自行编写的槽函数) 在MainWindow::MainWindow(QWidget *parent) :里面添加connect关联函数 //客户端点击 连接服务器,连接上会触发服务器发出newConnection的信号,server进入new_client函数中 //动作的发出者&sserver 服务器,发出的信号是newConnection //&QTcpServer中的这个函数newConnection会发出一个信号 动作的发出者是mserver服务器 connect(&sserver,&QTcpServer::newConnection,this,&MainWindow::receive_client);receive_client(自行编写的槽函数) //建立接收客户端连接的槽函数,有人连接就触发这个槽函数 void MainWindow::receive_client() { //获取这个服务器sserver与客户端通信的套接字 ssocket=sserver.nextPendingConnection(); //拿到套接字后,服务器可利用ssocket这个套接字中的write(),间接的向客户端发送数据, ssocket->write("connect"); //客户端如有写入,就会触发readyread这个信号 //关联一下客户端的写入信号,本来就是指针,不用取地址 //写在这里是确保客户端连接了服务器 //信号的发出者是ssocket 服务器与客户端之间通信的套接字 //当有东西写入的时候,就会发出readyread的信号 connect(ssocket,&QTcpSocket::readyRead,this,&MainWindow::sread_data); } 关于 ssocket=sserver.nextPendingConnection();想了很久,参考了其他的博客 我是这么理解的 在sserver这个服务器的进程汇总,调用nextPendingConnection()这个函数,获得了一个QtcpSocket类型的指针,就是服务端的套接字,用来和客户端通信的,所以在后面的内容中,直接向ssocket里面写入内容,客户端就可以收到。但是返回的这个QtcpSocket类型的指针不可以用于另一个线程。 在接收到新客户的这个函数中,再定义一个connect,是确保客户端连接了服务器,信号的发出者是ssocket,发出的信号是准备读readyRead,触发服务器去执行sread_data这个槽函数。 3.服务器发现有数据进来时,要去读取数据 //槽函数 //服务器读取客户端csocket发来的数据的槽函数,然后显示在服务器端的stextBrowser中 void MainWindow::sread_data() { // //获得信号的发送者的套接字 // //sender()用于服务器获取客户端在发送内容的时候的套接字,其实获取到的内容就是sscoket // //dynamic_cast 将sender获得的内容强制转换成QTcpSocket* // QTcpSocket *msocket = dynamic_cast(sender()); // //读取数据 // QString msg = msocket->readAll(); // //还可以读取对方的ip // QString ip = msocket->peerAddress().toString(); // //去掉前面的#ffff // ip.remove("::ffff:"); QString msg = ssocket->readAll(); QString ip = ssocket->peerAddress().toString(); //调用文本浏览框,显示内容 ui->stextBrowser->append(ip+":"+msg); }服务器读取客户发来的信息的时候,也是要先获取发送者的套接字QTcpSocket *msocket = dynamic_cast(sender());赋值给msock,这个临时创建的套接字,然后从这个临时创建的套接字中读取信息,还可以读取ip sender()函数,返回的是信号来源的对象,返回的就是,是谁进入了发出的信号,进入的这个槽函数。 4.服务端发送数据给客户端 //服务器端的 发送按钮 向客户端csocket写入数据 void MainWindow::on_pushButton_3_clicked() { //获取数据 toPlainText()这个组件转字符串 QString data = ui->stextEdit->toPlainText(); ssocket->write(data.toUtf8()); }由于ssocket是全局变量,所以上面在第三步中给它赋值了,这里就可以直接用了,直对它写入数据即可。 //服务器端的清空按钮 void MainWindow::on_pushButton_6_clicked() { //清空一下textedit ui->stextEdit->clear(); } 四 .cpp中客户端的内容 1.客户端连接服务器 //client端的连接服务器按钮 void MainWindow::on_pushButton_clicked() { // 根据输入的ip和port连接指定的服务器 csocket.connectToHost(ui->cipEdit->text(),ui->cportEdit->text().toUShort()); qDebug() //清空一下textedit ui->ctextEdit->clear(); } 3.客户端接收内容首先在MainWindow::MainWindow(QWidget *parent) :中建立connect连接 //关联一下信号 作用是读取服务端发来的数据 //当客户端发现有数据要进来的时候,就会发出readyread这个信号,触发读取并显示数据的槽函数 connect(&csocket,&QTcpSocket::readyRead,this,&MainWindow::cread_data);槽函数 //client端的接收服务器发来的数据的槽函数 void MainWindow::cread_data() { //通过套接字读取,保存服务器发过来的数据 QString msg = csocket.readAll(); //把数据放到文本浏览框中显示 ui->ctextBrowser->append(msg); } 小结客户端和服务端一边一个套接字,服务器端还要加一个服务端的对象用于监听 客户端的套接字csocket(是一个变量)可以直接使用,但是服务端的套接字ssocket的赋值是在服务器对象监听到有东西来连接的时候,通过nextPendingConnection获得的,是一个指针。 服务器向客户端写东西:sscoket->write() 客户端向服务器写东西:cscoket.write() 读取服务器获得的内容ssocket->readAll(); 读取客户端获得的内容 csocket.readAll(); |
CopyRight 2018-2019 实验室设备网 版权所有 |